using MeetingManagement.Domain.Common;
using System.Text.RegularExpressions;

namespace MeetingManagement.Domain.Entities
{
    public class User : AggregateRoot
    {
        public string Username { get; private set; }
        public string Email { get; private set; }
        public string PasswordHash { get; private set; }
        public bool IsActive { get; private set; }
        public string Role { get; private set; }


        public DateTime? LastLogin { get; private set; }

        public List<Meeting> Meetings { get; private set; } = new List<Meeting>();

        protected User()
        {
        }

        public static User Create(string username, string email, string passwordHash, string role = "User")
        {
            ValidateUsername(username);
            ValidateEmail(email);

            if (string.IsNullOrWhiteSpace(passwordHash))
                throw new ArgumentException("密码哈希不能为空", nameof(passwordHash));

            return new User
            {
                Id = Guid.NewGuid(),
                Username = username,
                Email = email,
                PasswordHash = passwordHash,
                IsActive = true,
                Role = role,
                CreatedDate = DateTime.UtcNow,
                UpdatedDate = DateTime.UtcNow
            };
        }

        private static void ValidateUsername(string username)
        {
            if (string.IsNullOrWhiteSpace(username))
                throw new ArgumentException("用户名不能为空", nameof(username));

            if (username.Length < 3 || username.Length > 50)
                throw new ArgumentException("用户名长度必须在3-50个字符之间", nameof(username));
        }

        private static void ValidateEmail(string email)
        {
            if (string.IsNullOrWhiteSpace(email))
                throw new ArgumentException("邮箱不能为空", nameof(email));

            var regex = new Regex(@"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$");
            if (!regex.IsMatch(email))
                throw new ArgumentException("邮箱格式不正确", nameof(email));
        }

        public void Deactivate()
        {
            if (!IsActive) return;

            IsActive = false;
            UpdatedDate = DateTime.UtcNow;
        }

        public void Activate()
        {
            if (IsActive) return;

            IsActive = true;
            UpdatedDate = DateTime.UtcNow;
        }
        public void UpdateInfo(string username, string email)
        {
            ValidateUsername(username);
            ValidateEmail(email);

            Username = username;
            Email = email;

            UpdatedDate = DateTime.UtcNow;
        }

        public void AssignMeeting(Meeting meeting)
        {
            if (meeting == null)
                throw new ArgumentNullException(nameof(meeting));

            if (!IsActive)
                throw new InvalidOperationException("不能为非活跃用户分配会议");

            if (meeting.Status == MeetingStatus.Cancelled)
                throw new InvalidOperationException("不能分配已取消的会议");

            if (!Meetings.Contains(meeting))
            {
                Meetings.Add(meeting);

                if (!meeting.Participants.Contains(this))
                    meeting.AssignParticipant(this);

                UpdatedDate = DateTime.UtcNow;
            }
        }

        public bool HasRole(string role)
        {
            return Role.Equals(role, StringComparison.OrdinalIgnoreCase);
        }

        public bool IsAdmin()
        {
            return HasRole("Admin");
        }

        public void UpdatePassword(string passwordHash)
        {
            if (string.IsNullOrWhiteSpace(passwordHash))
                throw new ArgumentException("密码哈希不能为空", nameof(passwordHash));

            PasswordHash = passwordHash;
            UpdatedDate = DateTime.UtcNow;
        }

        public void UpdateRole(string role)
        {
            if (string.IsNullOrWhiteSpace(role))
                throw new ArgumentException("角色不能为空", nameof(role));

            Role = role;
            UpdatedDate = DateTime.UtcNow;
        }

        public void RecordLogin()
        {
            LastLogin = DateTime.UtcNow;
            UpdatedDate = DateTime.UtcNow;
        }

        public bool IsOrganizerOf(Meeting meeting)
        {
            if (meeting == null)
                throw new ArgumentNullException(nameof(meeting));

            return meeting.OrganizerId == Id;
        }

        public bool IsParticipantOf(Meeting meeting)
        {
            if (meeting == null)
                throw new ArgumentNullException(nameof(meeting));

            return meeting.ParticipantIds.Contains(Id);
        }
    }
}
